from abc import ABCMeta, abstractmethod
from enum import Enum


# 工厂模式：简单工厂模式、工厂方法模式、抽象工厂模式
# 简单工厂模式：定义一个创建对象（实例化对象）的接口，通过参数来决定创建哪个类的实例
# 工厂方法模式：定义一个创建对象（实例化对象）的接口，让子类来决定创建哪个对象的实例。工厂方法使一个类的实例化延伸到其子类
# 抽象工厂模式：提供一个创建一系列相关或相互依赖对象的接口，而无需指定它们的具体类


class PenType(Enum):
    """画笔的类型"""
    PenTypeLine = 1
    PenTypeRect = 2
    PenTypeEllipse = 3


class Pen(metaclass=ABCMeta):
    """画笔"""
    def __init__(self, name):
        self.__name = name

    @abstractmethod
    def getType(self):
        pass

    def getName(self):
        return self.__name


class LinePen(Pen):
    """直线画笔"""
    def __init__(self, name):
        super().__init__(name)

    def getType(self):
        return PenType.PenTypeLine

class RectanglePen(Pen):
    """矩形画笔"""
    def __init__(self, name):
        super().__init__(name)

    def getType(self):
        return PenType.PenType.RectanglePen


class EllipsePen(Pen):
    """椭圆画笔"""
    def __init__(self, name):
        super().__init__(name)

    def getType(self):
        return PenType.PenType.RectanglePen


class PenFactory:
    """画笔工厂类"""
    def __init__(self):
        """定义一个字典（key:PenType,value:Pen)来存放对象，确保每一个类型只会一个对象"""
        self.__pens = {}

    def createPen(self, penType):
        """创建画笔"""
        if self.__pens.get(penType) is None:
            """如果该对象不存在，则创建一个对象并存到字典中"""
            if penType == PenType.PenTypeLine:
                pen = LinePen("直线画笔")
            elif penType == PenType.PenTypeRect:
                pen = RectanglePen("矩形画笔")
            elif penType == PenType.PenTypeEllipse:
                pen = EllipsePen("椭圆画笔")
            else:
                pen = Pen("")
            self.__pens[penType] = pen
        return self.__pens[penType]


if __name__ == "__main__":
    factory = PenFactory()

    linePen = factory.createPen(PenType.PenTypeLine)

    rectPen = factory.createPen(PenType.PenTypeRect)

    ellipsePen = factory.createPen(PenType.PenTypeEllipse)


    
